// SDPContent.h: interface for the CSDPContent class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SDPCONTENT_H__EE87741F_B424_470E_9B9D_C7AE9ABCB185__INCLUDED_)
#define AFX_SDPCONTENT_H__EE87741F_B424_470E_9B9D_C7AE9ABCB185__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "SIPHeader.h"
#include "mystring.h"
#include "base.h"
using namespace std;
class BASE_API CSDPContent : public CSIPContent 
{
public:
	struct Origin{
		Origin(){sessionid=0;version=0;};
		mystring	username;
		unsigned long	sessionid;
		unsigned long	version;
		mystring	networktype;
		mystring	addresstype;
		mystring	address;
	};
	struct Connection{
		Connection(){ttl=0;numberofaddress=0;};
		mystring	networktype;
		mystring	addresstype;
		mystring	connectionaddress;
		int		ttl;
		int		numberofaddress;
	};
	struct Bandwidth{
		mystring	modifier;
		int		bandwidthvalue;
	};
	struct Times{
		unsigned long	starttime;
		unsigned long	stoptime;
	};
	struct RepeatTimes{
		unsigned long				repeatinterval;
		unsigned long				activeduration;
		list<unsigned long>	offsetlist;
	};
	struct Attribute{
		mystring	att_field;
		mystring	att_value;
	};
	struct Media{
		Media& operator=(const Media& rhs)
		{
			media = rhs.media;
			port = rhs.port;
			numberofport = rhs.numberofport;
			transport = rhs.transport;
			while(formatlist.empty() == false)
			{
				formatlist.pop_front();
			}
			for(list<mystring>::const_iterator it = rhs.formatlist.begin();it != rhs.formatlist.end();it++)
			{
				formatlist.push_back(*it);
			}
			return *this;
		};
		mystring	media;
		int			port;
		int			numberofport;
		mystring		transport;
		list<mystring>	formatlist;
	};
	struct MediaDescription{
		MediaDescription()
		{connection = NULL;bandwidth = NULL;};
		~MediaDescription()
		{
			if(connection)delete connection;
			if(bandwidth)delete bandwidth;
			while(attributelist.empty() == false)attributelist.pop_front();
		};
		MediaDescription& operator=(const MediaDescription& rhs)
		{
			this->mediatitle = rhs.mediatitle;
			if(rhs.connection)
			{
				if(connection == NULL)
					connection = new struct Connection;
				*connection = *rhs.connection;
			}
			else if(connection)
			{
				delete connection;
				connection = NULL;
			}
			if(rhs.bandwidth)
			{
				if(bandwidth == NULL)
					bandwidth = new struct Bandwidth;
				*bandwidth = *rhs.bandwidth;
			}
			else if(bandwidth)
			{
				delete bandwidth;
				bandwidth = NULL;
			}
			media =rhs.media;
			
			while(attributelist.empty() == false)
			{
				attributelist.pop_front();
			}
			if(rhs.attributelist.size())
			{
				for(list<struct Attribute>::const_iterator it = rhs.attributelist.begin();it != rhs.attributelist.end();it++)
				{
					attributelist.push_back(*it);
				}
			}
			return *this;
		};
		struct Media			media;//m=
		mystring				mediatitle;//i=
		struct Connection*		connection;//c=
		struct Bandwidth*		bandwidth;//b=
		list<struct Attribute>	attributelist;//a=
	};
	void SetSessionName(const char *pname){sessionname = pname;};
	mystring &GetSessionName(){return sessionname;};
	const mystring &GetSessionName()const{return sessionname;};
	void setsessiondescription(const char *pd){sessiondescription = pd;};
	mystring &GetSessionDescription(){return sessiondescription;};
	const mystring &GetSessionDescription()const{return sessiondescription;};
	void SetURI(const char *puri){uri = puri;};
	mystring &GetURI(){return uri;};
	const mystring &GetURI()const{return uri;};
	void SetEMail(const char *pe){emailaddress = pe;};
	mystring &GetEMail(){return emailaddress;};
	const mystring &GetEMail()const {return emailaddress;};
	void SetPhoneNumber(const char *pp){phonenumber = pp;};
	mystring &GetPhoneNumber(){return phonenumber;};
	const mystring &GetPhoneNumber()const{return phonenumber;};

	void SetConnection(const struct Connection &conn)
	{
		if(connection == NULL)		
			connection = new struct Connection;
		*connection = conn;		
	};
	struct Connection *GetConnection(){return connection;};
	const struct Connection *GetConnection()const{return connection;};

	void SetOrigin(const struct Origin &o){
		if(origin == NULL)
			origin = new struct Origin;
		*origin = o;
	};
	struct Origin *GetOrigin(){return origin;};
	const struct Origin *GetOrigin()const{return origin;};
	
	void SetBandwidth(const struct Bandwidth &bw){
		if(bandwidth == NULL)
			bandwidth = new struct Bandwidth;
		*bandwidth = bw;
	};
	struct Bandwidth *GetBandwidth(){return bandwidth;};
	const struct Bandwidth *GetBandwidth()const{return bandwidth;};

	void SetTimes(const struct Times &t)
	{
		if(times == NULL)
			times = new struct Times;
		*times = t;
	};
	struct Times *GetTimes(){return times;};
	const struct Times *GetTimes()const{return times;};

	void SetRepeatTimes(const struct RepeatTimes &rt)
	{
		if(repeattimes == NULL)
			repeattimes = new struct RepeatTimes;
		*repeattimes = rt;
	};
	struct RepeatTimes *GetRepeatTimes(){return repeattimes;};
	const struct RepeatTimes *GetRepeatTimes()const{return repeattimes;};
	
	void AddMediaDescription(const struct MediaDescription &md)
	{
		struct MediaDescription *mmd = new struct MediaDescription;
		if(md.bandwidth)
		{
			mmd->bandwidth = new struct Bandwidth;
			*mmd->bandwidth = *md.bandwidth;
		}
		else
			mmd->bandwidth = NULL;
		if(md.connection)
		{
			mmd->connection = new struct Connection;
			*mmd->connection = *md.connection;
		}
		else
			mmd->connection = NULL;
		if(md.attributelist.size() > 0)
		{
			mmd->attributelist = md.attributelist;
		}
		mmd->media = md.media;
		mmd->mediatitle = md.mediatitle;
		medialist.push_back(mmd);
	};

	void AddAttribute(const struct Attribute &a)
	{
		attributelist.push_back(a);
	}
	list<struct Attribute> *GetAttributeList(){return &attributelist;};
	const list<struct Attribute> *GetAttributeList()const{return &attributelist;};
	list<struct MediaDescription*> *GetMediaList(){return &medialist;};
	const list<struct MediaDescription*> *GetMediaList()const{return &medialist;};
	virtual void SetContent(const char *pbuf,int len);
	virtual mystring Encoding();
	void ParseContent(){if(m_pContent)Parse(m_pContent,m_nLength);};
	void Clear();
	CSDPContent& operator=(const CSDPContent& rhs);
	CSDPContent();
	CSDPContent(const CSDPContent &sdp)
	{
		version = 0;	
		//mystring				sessionname;

		//mystring				sessiondescription;
		//mystring				uri;
		//mystring				emailaddress;
		//mystring				phonenumber;
		origin = NULL;
		connection = NULL;
		bandwidth = NULL;
		times = NULL;
		repeattimes = NULL;
		*this = sdp;
	};
	virtual ~CSDPContent();
private:
	int Parse(const char *pbuf,int len);
	int	ParseVersion(const char *p,int len,int &version);//v=
	int ParseOrigin(const char *p,int len,struct Origin &o);//o=
	int ParseSessionName(const char *p,int len,mystring &s);//s=
	int ParseSessionDescription(const char *p,int len,mystring &i);//i=
	int ParseURI(const char *p,int len,mystring &u);//u=
	int ParseEMail(const char *p,int len,mystring &e);//e=
	int ParsePhoneNumber(const char *pbuf,int len,mystring &p);//p=
	int ParseConnectionInformation(const char *p,int len,struct Connection &c);//c=
	int ParseBandwidthInformation(const char *p,int len,struct Bandwidth &b);//b=
	int ParseAttribute(const char *p,int len,struct Attribute &a);//a=
	int ParseTimes(const char *p,int len,struct Times&t);//t=
	int ParseRepeatTimes(const char *p,int len,struct RepeatTimes &r);//r=
	int ParseMedia(const char *p,int len,struct Media &m);//m=
	int ParseMediaDescription(const char *p,int len,struct MediaDescription &md);
	int ParseUnknown(const char *p,int len);
private:
	int					version;
	mystring				sessionname;
	mystring				sessiondescription;
	mystring				uri;
	mystring				emailaddress;
	mystring				phonenumber;
	struct Origin*		origin;
	struct Connection*	connection;
	struct Bandwidth*	bandwidth;
	struct Times*		times;
	struct RepeatTimes*	repeattimes;
	list<struct MediaDescription*>	medialist;
	list<struct Attribute>	attributelist;
};

#endif // !defined(AFX_SDPCONTENT_H__EE87741F_B424_470E_9B9D_C7AE9ABCB185__INCLUDED_)
